import React, {
  useCallback,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import {
  Button,
  Col,
  Empty,
  Input,
  List,
  Modal,
  Row,
  Comment as AntComment,
  message,
  Avatar,
} from 'antd';
import { findIndex, groupBy } from 'lodash';
import './index.local.less';
import {
  AddOrUpdateComment,
  DeleteComment,
  GetDocCommentList,
} from './service';
import { InbizComment } from './typings';
import { formatDate } from '@inbiz/utils';
import { getMessage, TextWidget } from '@inbiz/react';
import EmptyImage from './assets/no-data.svg';

const Comment: React.FC<{
  visible: boolean;
  onCancel: () => void;
  config: {
    docId: number;
    docType?: 1 | 2;
  };
  userInfo: Record<string, any>;
}> = (props) => {
  const { visible, onCancel, config, userInfo } = props;
  const replyInputRef = useRef(null);
  const [comment, _comment] = useState<string>('');
  const [data, _data] = useState([]);
  const [replyTarget, _replyTarget] = useState<InbizComment>(null);
  const [pickerVisible, _pickerVisible] = useState(false);
  const [pageNo, _pageNo] = useState(1);
  const pageSize = 10;
  const [total, _total] = useState(0);
  const [submiting, _submiting] = useState(false);

  const onRefresh = useCallback(() => {
    GetDocCommentList({
      pageNum: 1,
      pageSize: 10,
      docId: config.docId,
      docType: config.docType,
    }).then((res) => {
      if (res?.data?.CommentList) {
        let commentIdMap = {};
        res?.data?.CommentList.map((item) => {
          commentIdMap[item.CommentId] = item;
        });
        const groups = groupBy(res.data.CommentList, 'ParentCommentId');
        let newData = groups['0'] || [];
        for (let key in groups) {
          if (key != '0') {
            let index = findIndex(newData, { CommentId: Number(key) });
            if (index > -1) {
              (groups[key] || []).map((item: InbizComment) => {
                item.TargetUserId = commentIdMap[key].UserId;
                item.TargetUserName = commentIdMap[key].UserRealName;
              });
              newData.splice(index + 1, 0, ...groups[key]);
            }
          }
        }
        _data(newData);
        _pageNo(1);
        _total(res.count);
      }
    });
  }, [config.docId, config.docType]);

  const addOrUpdateComment = useCallback(() => {
    let content = comment?.trim() || '';
    if (!content) {
      replyInputRef.current?.focus?.();
      // 请输入内容
      return message.error(getMessage('FolderPanel.lang.noContent'));
    }
    _submiting(true);
    AddOrUpdateComment({
      docId: config.docId,
      comment: content,
      annotationId: replyTarget?.CommentId,
    })
      .then((res) => {
        if (res?.result == 0) {
          // 发表成功
          message.success(getMessage('FolderPanel.lang.publishedSuccessfully'));
          onRefresh();
        } else if (res?.result == 601) {
          message.error(getMessage('FolderPanel.lang.filesHadDel'));
        } else {
          message.error(getMessage('FolderPanel.lang.commentFailed'));
        }
      })
      .finally(() => {
        _comment('');
        _submiting(false);
        _replyTarget(null);
      });
  }, [config.docId, comment, replyTarget, onRefresh, replyInputRef.current]);

  const reply = useCallback((item: InbizComment) => {
    replyInputRef.current?.focus();
    _replyTarget(item);
  }, []);

  const unreply = useCallback(() => {
    _replyTarget(null);
    _comment('');
  }, []);

  const deleteComment = useCallback(
    (item: InbizComment) => {
      Modal.confirm({
        // 确认删除
        title: getMessage('FolderPanel.lang.sureToDelete'),
        // 确认要删除此评论吗？
        content: getMessage('FolderPanel.lang.ifSureToDelete'),
        okText: getMessage('FolderPanel.lang.action.ok'),
        cancelText: getMessage('FolderPanel.lang.action.cancel'),
        onOk() {
          DeleteComment({
            commentId: item.CommentId,
            docType: config.docType,
          }).then((res) => {
            if (res.result == 0) {
              // 删除成功
              message.success(getMessage('FolderPanel.lang.deleteSuccess'));
              onRefresh();
            }
          });
        },
      });
    },
    [onRefresh, config.docType],
  );

  const addEmoji = useCallback(
    (emoji) => {
      _comment(`${comment || ''}${emoji}`);
      _pickerVisible(false);
    },
    [comment],
  );

  const renderItem = useCallback(
    (item: InbizComment, index: number) => {
      const creatTime = formatDate(item.CommentCreateTime);
      return (
        <AntComment
          className={'comment'}
          actions={[
            item?.UserId == inbiz?.userInfo?.id && (
              <a
                key="reply"
                className={'delete'}
                onClick={(e) => deleteComment(item)}
              >
                {/* 删除 */}
                <TextWidget>FolderPanel.lang.action.delete</TextWidget>
              </a>
            ),
            replyTarget?.CommentId == item.CommentId ? (
              <a
                key="reply"
                onClick={(e) => unreply()}
                className={'reply'}
              >
                {/* 取消回复 */}
                <TextWidget>FolderPanel.lang.cancelReply</TextWidget>
              </a>
            ) : (
              <a
                key="reply"
                onClick={(e) => reply(item)}
                className={'reply'}
              >
                {/* 回复 */}
                <TextWidget>FolderPanel.lang.reply</TextWidget>
              </a>
            ),
          ]}
          author={<span>{item.UserRealName}</span>}
          avatar={
            <Avatar
              src={`/ImageType/GetUserAvatar?m=${Math.random()}&userId=${item.UserId
                }`}
              alt="Han Solo"
            />
          }
          key={`${index}`}
          content={
            <span className={'commentContent'}>
              {item.TargetUserName ? (
                <span className={'replayToUser'}>
                  <TextWidget>FolderPanel.lang.reply</TextWidget>{' '}
                  {item.TargetUserName}
                </span>
              ) : null}
              {unescape(item.CommentContent)}
            </span>
          }
          datetime={<span>{creatTime}</span>}
        />
      );
    },
    [replyTarget],
  );

  useEffect(() => {
    onRefresh();
  }, []);

  return (
    <Modal
      title={getMessage('FolderPanel.lang.action.comment')}
      width={625}
      bodyStyle={{
        height: 480,
        overflow: 'auto',
      }}
      visible={visible}
      onCancel={onCancel}
      maskClosable={false}
      footer={
        <Row className={'footer'}>
          <Col flex={1}>
            <Input
              className={'input'}
              ref={replyInputRef}
              placeholder={
                replyTarget
                  ? `${getMessage('FolderPanel.lang.reply')}:` +
                  replyTarget.UserRealName
                  : getMessage('FolderPanel.lang.plzEnter')
              }
              value={comment}
              onChange={(e) => _comment(e.target.value)}
            />
          </Col>
          <Col>
            <Button
              className={'okBtn'}
              loading={submiting}
              type="primary"
              onClick={(e) => {
                if (submiting) return;
                addOrUpdateComment();
              }}
            >
              {/* 确定 */}
              <TextWidget>FolderPanel.lang.action.ok</TextWidget>
            </Button>
          </Col>
        </Row>
      }
    >
      {data.length ? (
        <List className={'list'}>{data.map(renderItem)}</List>
      ) : (
        <Empty
          className={'empty'}
          image={
            <img width={60} height={60} src={EmptyImage} />
          }
          description={
            // 暂无评论，快来发条评论吧
            <span style={{ color: '#ccc', userSelect: 'none' }}>
              <TextWidget>FolderPanel.lang.needContent</TextWidget>
            </span>
          }
        />
      )}
    </Modal>
  );
};

Comment.defaultProps = {
  config: {
    docId: -1,
    docType: 2,
  },
};

export default Comment;
